package com.gold.security;


import com.gold.common.JsonUtils;
import com.gold.common.filters.TokenAuthFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;

import javax.annotation.Resource;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Arrays;

/**安全配置类
 * @author XiaoHao
 * @date 2022-05-07 15:53
 */
@EnableGlobalMethodSecurity(prePostEnabled = true)
@EnableWebSecurity
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Resource
    LoginValidateAuth loginValidateAuth;

    @Override
    public void configure(AuthenticationManagerBuilder auth) throws Exception {
            auth.authenticationProvider(loginValidateAuth);
    }

    /**
     * 配置拦截规则
     *
     * @param http
     * @throws Exception
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //配置不拦截
        http.authorizeRequests()
                //登录  激活  退出  注册
                .antMatchers("/login","/active","/logout","/register")
                .permitAll()
                .anyRequest()
                .authenticated();

        http.formLogin()
                .loginPage("/index.html")
                //登录成功
                .successHandler(new AuthSuccessHandler())
                .loginProcessingUrl("/login")
                //登录失败
                .failureHandler(new AuthFailureHandler())
                //退出登录
                // 开启跨域配置
                .and()
                .cors()
                .configurationSource(corsConfigurationSource())
                .and()
                .csrf()
                .disable()
                .exceptionHandling().authenticationEntryPoint(new AuthenticationEntryPoint() {
            @Override
            public void commence(HttpServletRequest httpServletRequest, HttpServletResponse response, AuthenticationException e) throws IOException, ServletException {
                //设置返回请求头
                response.setContentType("application/json;charset=utf-8");
                PrintWriter out = response.getWriter();
                out.write(JsonUtils.responseJson(false,300,"请先登录账号，或者联系管理员","").toJSONString());
                out.flush();
                out.close();
            }
        })
        ;
        http.logout().logoutUrl("/logout").logoutSuccessHandler(new MyLogoutSuccessHandler());
        http.addFilter(new TokenAuthFilter(authenticationManager()));
        http.addFilter(usernamePasswordJsonAuth());
        http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
    }

    @Bean
    UsernamePasswordJsonAuth usernamePasswordJsonAuth()throws Exception{
        UsernamePasswordJsonAuth filter= new UsernamePasswordJsonAuth();
        filter.setAuthenticationSuccessHandler(new AuthSuccessHandler());
        filter.setAuthenticationFailureHandler(new AuthFailureHandler());
        filter.setAuthenticationManager(authenticationManagerBean());
        return filter;
    }
    CorsConfigurationSource corsConfigurationSource() {
        // 提供CorsConfiguration实例，并配置跨域信息
        CorsConfiguration corsConfiguration = new CorsConfiguration();
        corsConfiguration.setAllowedHeaders(Arrays.asList("*"));
        corsConfiguration.setAllowedMethods(Arrays.asList("*"));
        corsConfiguration.setAllowedOrigins(Arrays.asList("*"));
        corsConfiguration.setMaxAge(3600L);
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", corsConfiguration);
        return source;
    }

}
